#include <qhttp.mqh>
#property indicator_chart_window

extern bool		ClearOnTrigger	= true;
extern bool		PopupAlert	= true;
extern bool    TakeTrades = false;
extern string  Asset = "EUR/USD";
extern string  APIKey = "";
extern string  IndiName = "MT4 Binary Trader";
extern string tradeSize = "25.00";
extern string ipaddress = "127.0.0.1";
extern string port = "8090";
extern bool BidAsk = true;

int init() {
}

int deinit() {
}

double getPrice() {
   if(BidAsk) return ((Bid+Ask)/2);
   return(Bid);
}

int start() {

	// Iterate over objects on this chart
	for (int i=ObjectsTotal()-1;i>=0;i--) {
		string	sObjName 	= ObjectName(i);
		double	dObjPrice;
		int		iObjAlert;
		int		iProximity;
		string	sMessage;
		
		// Can we get a price for this object?  If not, continue iteration
		dObjPrice = getObjectPrice(sObjName);
		if (dObjPrice == -1) continue;
		
		// Is there an trade on this object?  If not, continue iteration
		iObjAlert = getObjectTrade(sObjName);
		if (iObjAlert == -1) continue;
		
		if (getObjectTradeType(sObjName)=="Put"){
		
		  if(getObjectTradeReverse(sObjName)) if(getPrice() < dObjPrice) continue;
		  if(!getObjectTradeReverse(sObjName)) if(getPrice() > dObjPrice) continue;
		  
		  if(TakeTrades){
		    takeTrade("Put",Asset,tradeSize,getObjectTradeExpiry(sObjName),APIKey,IndiName,DoubleToStr(getPrice(),Digits));
		    // Clear the alert from the object description
		    if(ClearOnTrigger){
		     clearObjectAlert(sObjName);
		    }
		  }
		  
		} else if (getObjectTradeType(sObjName)=="Call"){
		  
		  // take trade
		  if(getObjectTradeReverse(sObjName)) if(getPrice() > dObjPrice) continue;
		  if(!getObjectTradeReverse(sObjName)) if(getPrice() < dObjPrice) continue;
		  
		  if(TakeTrades){
		    takeTrade("Call",Asset,tradeSize,getObjectTradeExpiry(sObjName),APIKey,IndiName,DoubleToStr(getPrice(),Digits));
		    // Clear the alert from the object description
		    if(ClearOnTrigger){
		     clearObjectAlert(sObjName);
		    }
		  }
		  
		} else {
		  continue;
		}
	}

	return(0);
}

double getObjectPrice(string sObjName) {

	int iObjType = ObjectType(sObjName);
	
	// if it's a horizontal line...
	if (iObjType == OBJ_HLINE)
		return(ObjectGet(sObjName,OBJPROP_PRICE1));
	
	// if it's a trend line...
	if (iObjType == OBJ_TREND)
		return(ObjectGetValueByShift(sObjName,0));
	
	// otherwise...
	return(-1);
}

int getObjectTrade(string sObjName) {

	// looking for pattern "Call_##" at end of obj description
	string 	sObjectDesc		= ObjectDescription(sObjName);
	int 	iPatternOffset 	= StringFind(sObjectDesc,"Call_");
	int		iPatternLength	= StringLen("Call_");

	// if pattern not found, no alert for this object
	if (iPatternOffset == -1){
	  iPatternOffset 	= StringFind(sObjectDesc,"Put_");
	  iPatternLength	= StringLen("Put_");
	}
		
	if (iPatternOffset == -1) 
		return(-1);
	
	// return value after the pattern as number
	return(StrToInteger(StringSubstr(sObjectDesc,iPatternOffset+iPatternLength)));
}


string getObjectTradeExpiry(string sObjName) {

	// looking for pattern "Call_##" at end of obj description
	string 	sObjectDesc		= ObjectDescription(sObjName);
	int 	iPatternOffset 	= StringFind(sObjectDesc,"Call_");
	int		iPatternLength	= StringLen("Call_");

	// if pattern not found, no alert for this object
	if (iPatternOffset == -1){
	  iPatternOffset 	= StringFind(sObjectDesc,"Put_");
	  iPatternLength	= StringLen("Put_");
	}
		
	if (iPatternOffset == -1) 
		return(-1);
	
	// return value after the pattern as number
	return(StringSubstr(sObjectDesc,iPatternOffset+iPatternLength));
}

string getObjectTradeType(string sObjName) {

	// looking for pattern "Call_##" at end of obj description
	string 	sObjectDesc		= ObjectDescription(sObjName);
	int 	iPatternOffset 	= StringFind(sObjectDesc,"Call_");
	int		iPatternLength	= StringLen("Call_");
	string type = "Call";

	// if pattern not found, no alert for this object
	if (iPatternOffset == -1){
	  iPatternOffset 	= StringFind(sObjectDesc,"Put_");
	  iPatternLength	= StringLen("Put_");
	  type = "Put";
	}
		
	if (iPatternOffset == -1) 
		return(-1);
	
	// return value after the pattern as number
	return(type);
}

bool getObjectTradeReverse(string sObjName) {

	// looking for pattern "Call_##" at end of obj description
	string 	sObjectDesc		= ObjectDescription(sObjName);
	int 	iPatternOffset 	= StringFind(sObjectDesc,"Reverse_");
	int		iPatternLength	= StringLen("Reverse_");
		
	if (iPatternOffset == -1) 
		return(false);
	
	// return value after the pattern as number
	return(true);
}

void clearObjectAlert(string sObjName) {

	// strip from end of obj description
	string 	sObjDesc 		= ObjectDescription(sObjName);
	int 	iSubStrOffset 	= StringFind(sObjDesc,"Call_");
	
	// if found at start of description, clear description
	if (iSubStrOffset == 0) {
		ObjectSetText(sObjName,"");
		return;
	}
	
	// if found further on in desc, strip it from description
	if (iSubStrOffset > 0) {
		ObjectSetText(sObjName,StringSubstr(sObjDesc,0,iSubStrOffset));
		return;
	}
	
	iSubStrOffset 	= StringFind(sObjDesc,"Put_");
	
	// if found at start of description, clear description
	if (iSubStrOffset == 0) {
		ObjectSetText(sObjName,"");
	}
	
	// if found further on in desc, strip it from description
	if (iSubStrOffset > 0) {
		ObjectSetText(sObjName,StringSubstr(sObjDesc,0,iSubStrOffset));
	}
	
	iSubStrOffset 	= StringFind(sObjDesc,"Reverse_");
	
	// if found at start of description, clear description
	if (iSubStrOffset == 0) {
		ObjectSetText(sObjName,"");
	}
	
	// if found further on in desc, strip it from description
	if (iSubStrOffset > 0) {
		ObjectSetText(sObjName,StringSubstr(sObjDesc,0,iSubStrOffset));
	}
	
	return;
}

void takeTrade(string direction, string asset, string amount, string expiry, string api, string name, string rate){
   string response;
   string params [0,2];
   ArrayResize(params,0);
   
   addParam("mode",direction,params);
   addParam("asset",asset,params);
   addParam("amount",amount,params);
   addParam("expiry",expiry,params);
   addParam("api",api,params);
   addParam("name",name,params);
   addParam("rate",rate,params);
   
   string req = ArrayEncode(params);
   
   HttpGET("http://"+ipaddress+":"+port+"/?"+req,response);
   if(PopupAlert){
      Alert(direction + " trade request sent for " + asset + " - expiry " + expiry);
   }
}